﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using CultuRAM.DAL;
using CultuRAM.Models;
using Newtonsoft.Json;
using PagedList;
using Formatting = Newtonsoft.Json.Formatting;


namespace CultuRAM.Controllers
{
    
    public class EventController : Controller
    {
        //private readonly CultuRAMContext _db = new CultuRAMContext();
        public static UnitOfWork _unitOfWork = new UnitOfWork();
        private static string _sortOrderGlobal = String.Empty;
        private static string _stringFilterGlobal = String.Empty;
        private readonly ValidateLogin vLogin = new ValidateLogin();

        private int _pageSize = 6; //Ideal 6 (devido ao conteudo)
        

        //Cache Mode
        public static CacheMode _CacheMode = new CacheMode()
            {
                EventsList = new List<Event>(),
                EventPropValuesList = new List<EventPropertyValue>(),
                SessionsList = new List<Session>(),
                ParticipantsList = new List<EventParticipant>(),
                ResourcesList = new List<Resource>(),
                Active = false
            };

        // 
        // GET: /Event/HomeView/5

        public PartialViewResult HomeView(int id = 0)
        {
            var ev = _unitOfWork.EventRepository.GetByID(id);
            if (ev == null)
            {
                //int pageSize = 6;
                //int pageNumber = page != 0 ? page : 1; //page != 0 ?? page : 1
                //return PartialView("Index", _unitOfWork.EventRepository.Get());
            }

            ViewBag.Places = _unitOfWork.PlaceRepository.Get().ToList();
            return PartialView("_HomeView", ev);
        }


        //
        // GET: /Event/

        public ActionResult Index(string sortOrder, string stringFilter, int page = 0, int? hl = 0)
        {
            //Use in Filter
            ViewBag.EventTypeIdEv = new SelectList(_unitOfWork.EventTypeRepository.Get().OrderBy(o => o.Type), "TypeId", "Type");
            ViewBag.PlaceIdEv = new SelectList(_unitOfWork.PlaceRepository.Get().OrderBy(o => o.NamePlace), "PlaceId", "NamePlace");
            ViewBag.EntityIdEv = new SelectList(_unitOfWork.EntityRepository.Get().OrderBy(o => o.Name), "EntityId", "Name");
            ViewBag.StateIdEv = new SelectList(_unitOfWork.EventStateRepository.Get().OrderBy(o => o.State), "StateId", "State");
            ViewBag.PeriodIdEv = PopulatePeriodDropDownList();
            
            //Clear Cache
            ClearCache();
            var events = BuildEventList(sortOrder, stringFilter, page);
            
            return View(events);      
        }

        //
        // GET: /Event/

        public ActionResult IndexHl(string sortOrder, string stringFilter, int page = 0)
        {
            //Use in Filter
            ViewBag.EventTypeIdEv = new SelectList(_unitOfWork.EventTypeRepository.Get().OrderBy(o => o.Type), "TypeId", "Type");
            ViewBag.PlaceIdEv = new SelectList(_unitOfWork.PlaceRepository.Get().OrderBy(o => o.NamePlace), "PlaceId", "NamePlace");
            ViewBag.EntityIdEv = new SelectList(_unitOfWork.EntityRepository.Get().OrderBy(o => o.Name), "EntityId", "Name");
            ViewBag.StateIdEv = new SelectList(_unitOfWork.EventStateRepository.Get().OrderBy(o => o.State), "StateId", "State");
            ViewBag.PeriodIdEv = PopulatePeriodDropDownList();

            //Clear Cache
            ClearCache();
            var events = BuildEventListHl(sortOrder, stringFilter, page);

            return View(events);
        }

        //
        // GET/POST: /Event/IndexPv

        public ActionResult IndexPv(string sortOrder, string stringFilter, int page = 0)
        {
            var events = BuildEventList(sortOrder, stringFilter, page);
            return PartialView("_IndexPv", events);
        }

        //
        // GET/POST: /Event/IndexPvHl

        public ActionResult IndexPvHl(string sortOrder, string stringFilter, int page = 0)
        {
            var events = BuildEventListHl(sortOrder, stringFilter, page);
            return PartialView("_IndexPvHl", events);
        }

        //
        // GET: /Event/Details/5

        public ActionResult Details(int id = 0)
        {
            var ev = _unitOfWork.EventRepository.GetByID(id);

            if (ev == null)
            {
                return HttpNotFound();
            }
            return View(ev);
        }

        // PARTIAL VIEW
        // GET: /Event/Details/5

        public PartialViewResult DetailsPv(int page = 0, int id = 0)
        {
            var ev = _unitOfWork.EventRepository.GetByID(id);
            if (ev == null)
            {
                //int pageSize = 6;
                int pageNumber = page != 0 ? page : 1; //page != 0 ?? page : 1
                return PartialView("Index", _unitOfWork.EventRepository.Get().ToPagedList(pageNumber, _pageSize));
            }
            return PartialView("Details", ev);
        }

        //
        // GET: /Event/Create
        [Authorize]
        public ActionResult Create()
        {
            _CacheMode.Active = true;
            var last1 = _unitOfWork.EventRepository.Get().LastOrDefault();
            var evLastId = 0;

            if (last1 != null)
            {
                evLastId = last1.EventId;
            }
          
            var last2 = _CacheMode.EventsList.ToList().LastOrDefault();
            var evLastIdCache = 0;
            
            if (last2 != null)
            {
                evLastIdCache = last2.EventId;
            }

            var last3 = _unitOfWork.EventPropertyValueRepository.Get().LastOrDefault();
            int evpvLastId = 0;
            if (last3 != null)
            {
                evpvLastId = last3.PropertyValueId;
            }

            var ev = new Event {Poster = "/Images/Icones/icon_no_image.png"};
 
            
            //Criar evento temporario com propriedades base (Ex: Estado = "Pendente")
   
            var propOfType = GetAllProperties(_unitOfWork.EventTypeRepository.Get().FirstOrDefault(t => t.TypeId == 1)); //Tipo Genérico
            var listEvPropValue = new List<EventPropertyValue> { };
            var stateName = _unitOfWork.EventStateRepository.GetByID(1).State;
            var valueProp = String.Empty;

            ev.EventId = evLastIdCache == 0 ? evLastId + 1 : evLastIdCache + 1;
            ev.EventType = _unitOfWork.EventTypeRepository.GetByID(1);
            ev.EventTypeId = 1;
            ev.Entity = _unitOfWork.EntityRepository.GetByID(1); //OBTER A ENTIDADE A QUE PERTENCE O UTILIZADOR ********
            ev.EntityId = 1;
            ev.Title = "Sem Título...";
            ev.EventSessions = null;
            ev.EventParticipants = null;
            ev.Resources = null;
            ev.Comments = null;

            var evpLastIdTemp = evpvLastId;
            foreach (var item in propOfType)
            {
                evpLastIdTemp++;
                valueProp = item.Name.Contains("Estado") ? stateName : "";

                listEvPropValue.Add(
                    new EventPropertyValue() { PropertyValueId = evpLastIdTemp, Event = ev, EventProperty = item, Value = valueProp });
                _CacheMode.EventPropValuesList.Add(
                    new EventPropertyValue() { PropertyValueId = evpLastIdTemp, Event = ev, EventProperty = item, Value = valueProp });
            }
            
            //ev.PropertyValues = listEvPropValue.OrderBy(o => o.EventProperty.Name).ToPagedList(1, 7);
            ev.PropertyValues = listEvPropValue.OrderBy(o => o.EventProperty.Name).ToList();
            ev.PropertyValuesPaged = listEvPropValue.OrderBy(o => o.EventProperty.Name).ToPagedList(1, 7);

            ev.StartDate = DateTime.Now.Date + new TimeSpan(00, 00, 0);
            ev.EndDate = DateTime.Now.Date + new TimeSpan(00, 00, 0);

            ViewBag.EventTypeIdDdl = PopulateEventTypeDropDownList();
            ViewBag.PalceIdDdl = PopulatePlacesDropDownList();
            ViewBag.EntityIdDdl = PopulateEntityDropDownList();
            ViewBag.EventStateIdDdl = PopulateStatesDropDownList();
            ViewBag.EntityTypeIdDdl = PopulateEntityTypeDropDownList();
            ViewBag.CityIdDdl = PopulateCitiesDropDownList();
            ViewBag.ParticipIdDdl = PopulateParticipDropDownList();
            ViewBag.ParticipantTypeIdDdl = PopulateParticipTypeDropDownList();

            ev.ListEventTypes = _unitOfWork.EventTypeRepository.Get().ToPagedList(1, 7);
            ev.ListEntities = _unitOfWork.EntityRepository.Get().ToPagedList(1, 7);
            ViewBag.IdParam = 2;

            ViewBag.MsgDefProp = "Para gerir as Propriedades do evento selecione uma das opções à esquerda.";
            ViewBag.MsgDefSes = "Para gerir as Sessões do evento selecione uma das opções à esquerda.";
            ViewBag.MsgDefPar = "Para gerir os Participantes do evento selecione uma das opções à esquerda.";
            ViewBag.MsgDefRes = "Para gerir os Recursos do evento selecione uma das opções à esquerda.";

            _CacheMode.EventsList.Add(ev);

            ViewBag.ClassAdd = "alert alert-success";
            return View(ev);
        }

        //
        // POST: /Event/Create
        [Authorize]
        [HttpPost]
        public ActionResult Create(Event ev)
        {
            //ev.EventType = _unitOfWork.EventTypeRepository.GetByID(ev.EventType.TypeId);
            if (String.IsNullOrEmpty(ev.Title))
            {
                ev.Title = "Sem título...";
            }

            if (ModelState.IsValid)
            {
                try
                {
                    var evExist = _unitOfWork.EventRepository.GetByID(ev.EventId);
                    if (evExist == null)
                    {
                        //ev.Poster = "/Images/Icones/icon_no_image.png";
                        var listEvPropValueTemp = new List<EventPropertyValue> { };
                        var listEvSessionsTemp = new List<Session> { };
                        var listEvParticipantsTemp = new List<EventParticipant> { };
                        var listEvResourcesTemp = new List<Resource> { };

                        //TAB: PROPERTIES VALUES OF EVENT
                        foreach (var item in _CacheMode.EventPropValuesList.ToList())
                        {
                            item.Event = ev;
                            listEvPropValueTemp.Add(item);
                            _unitOfWork.EventPropertyValueRepository.Insert(item);
                        }
                        ev.PropertyValues = listEvPropValueTemp.ToList();
                        ev.PropertyValuesPaged = ev.PropertyValues.OrderBy(o => o.EventProperty.Name).ToPagedList(1, 7);
                        
                        //TAB: SESSIONS OF EVENT
                        foreach (var item in _CacheMode.SessionsList.ToList())
                        {
                            item.Event = ev;
                            listEvSessionsTemp.Add(item);
                            _unitOfWork.SessionRepository.Insert(item);
                        }
                        ev.EventSessions = listEvSessionsTemp.ToList();
                        ev.EventSessionsPaged = ev.EventSessions.OrderBy(o => o.Date).ToPagedList(1, 5);

                        //TAB: PARTICIPANTS OF EVENT
                        foreach (var item in _CacheMode.ParticipantsList.ToList())
                        {
                            item.Event = ev;
                            listEvParticipantsTemp.Add(item);
                            _unitOfWork.EventParticipantRepository.Insert(item);
                        }
                        ev.EventParticipants = listEvParticipantsTemp.ToList();
                        ev.EventParticipantsPaged = ev.EventParticipants.OrderBy(o => o.Participant.Name).ToPagedList(1, 7);

                        //TAB: RESOURCES OF EVENT
                        foreach (var item in _CacheMode.ResourcesList.ToList())
                        {
                            item.Event = ev;
                            listEvResourcesTemp.Add(item);
                            _unitOfWork.ResourceRepository.Insert(item);
                        }
                        ev.Resources = listEvResourcesTemp.ToList();
                        ev.ResourcesPaged = ev.Resources.OrderByDescending(o => o.ResId).ToPagedList(1, 7);


                        //Save Event, Properties, Sessions, Participants and Resources in BD
                        _unitOfWork.EventRepository.Insert(ev);
                        _unitOfWork.Save();

                        //Clear the Cache
                        ClearCache();


                        //Create folders of Event
                        var pathImg = Server.MapPath(String.Format("~/Content/Event/{0}/Img", ev.EventId));
                        var pathDoc = Server.MapPath(String.Format("~/Content/Event/{0}/Doc", ev.EventId));

                        if (!Directory.Exists(pathImg))
                            Directory.CreateDirectory(pathImg);

                        if (!Directory.Exists(pathDoc))
                            Directory.CreateDirectory(pathDoc);

                        return RedirectToAction("Index");
                    }
                    else
                    {
                        return RedirectToAction("Index");
                    }
                }
            
                catch (DataException e)
                {
                    var msgError = e;
                }
                
            }


            //ViewBag.EventTypeId = new SelectList(_unitOfWork.EventTypeRepository.Get(), "TypeId", "Type", ev.EventTypeId);
            //ViewBag.EntityId = new SelectList(_unitOfWork.EntityRepository.Get(), "EntityId", "Name", ev.EntityId);
            ViewBag.EventTypeIdDdl = PopulateEventTypeDropDownList(ev.EventTypeId);
            ViewBag.EntityIdDdl = PopulateEntityDropDownList(ev.EntityId);
    
           

            return View(ev);
        }


        //
        // GET: /Event/Edit/5
        [Authorize]
        public ActionResult Edit(int id = 0)
        {
            if (id != 0)
            {
                var ev = _unitOfWork.EventRepository.GetByID(id);

                if (ev == null)
                {
                    return HttpNotFound();
                }

                //const int page = 1;
                //const int pageNumber = page != 0 ? page : 1;

                //PROPERTIES LIST OF EVENT
                ev.PropertyValues = _unitOfWork.EventPropertyValueRepository.Get().Where(x => x.EventId == id).ToList();
                ev.PropertyValuesPaged = ev.PropertyValues.OrderBy(o => o.EventProperty.Name).ToPagedList(1, 7);
                //SESSIONS LIST OF EVENT
                ev.EventSessions = _unitOfWork.SessionRepository.Get().Where(x => x.EventId == id).ToList();
                ev.EventSessionsPaged = ev.EventSessions.OrderBy(o => o.Date).ToPagedList(1, 5);
                //PARTICIPANTS LIST OF EVENT
                ev.EventParticipants = _unitOfWork.EventParticipantRepository.Get().Where(x => x.EventId == id).ToList();
                ev.EventParticipantsPaged = ev.EventParticipants.OrderBy(o => o.Participant.Name).ToPagedList(1, 7);
                //RESOURCES LIST OF EVENT
                ev.Resources = _unitOfWork.ResourceRepository.Get().Where(x => x.EventId == id).ToList();
                ev.ResourcesPaged = ev.Resources.OrderByDescending(o => o.ResId).ToPagedList(1, 7);
                //COMMENTS LIST OF EVENT
                ev.Comments = _unitOfWork.CommentRepository.Get().Where(x => x.EventId == id).ToList();
                ev.CommentsPaged = ev.Comments.OrderByDescending(o => o.CommentId).ToPagedList(1, 7);

                ViewBag.EventTypeIdDdl = PopulateEventTypeDropDownList();
                ViewBag.PalceIdDdl = PopulatePlacesDropDownList();
                ViewBag.EntityIdDdl = PopulateEntityDropDownList();
                ViewBag.EventStateIdDdl = PopulateStatesDropDownList();
                ViewBag.EntityTypeIdDdl = PopulateEntityTypeDropDownList();
                ViewBag.CityIdDdl = PopulateCitiesDropDownList();
                ViewBag.ParticipIdDdl = PopulateParticipDropDownList();
                ViewBag.ParticipantTypeIdDdl = PopulateParticipTypeDropDownList();

                ViewBag.MsgDefProp = "Para gerir as Propriedades do evento selecione uma das opções à esquerda.";
                ViewBag.MsgDefSes = "Para gerir as Sessões do evento selecione uma das opções à esquerda.";
                ViewBag.MsgDefPar = "Para gerir os Participantes do evento selecione uma das opções à esquerda.";
                ViewBag.MsgDefRes = "Para gerir os Recursos do evento selecione uma das opções à esquerda.";

                //string dateStr = ev.Date.ToString("dd-MM-yyyy");
                //ev.Date = DateTime.Parse(dateStr);

                return View(ev);
            }
            else
            {
                ViewBag.MsgWarning = "Para Editar um evento tem de selecionar o registo pretendido!";
                return View("Default");
            }
            
        }

        //
        // POST: /Event/Edit/5
        [Authorize]
        [HttpPost]
        public ActionResult Edit(Event ev)
        {
            ev.EventType = _unitOfWork.EventTypeRepository.GetByID(ev.EventTypeId);
            ev.Entity = _unitOfWork.EntityRepository.GetByID(ev.EntityId);

            if (ModelState.IsValid)
            {
                var evTemp = new Event()
                    {
                        EventId = ev.EventId,
                        Title = ev.Title,
                        Poster = ev.Poster,
                        StartDate = ev.StartDate,
                        EndDate = ev.EndDate,
                        Duration = ev.Duration,
                        Public = ev.Public,
                        EventTypeId = ev.EventTypeId,
                        EventType = ev.EventType,
                        EntityId = ev.EntityId,
                        Entity = ev.Entity,
                        PropertyValues = ev.PropertyValues,
                        EventSessions = ev.EventSessions,
                        EventParticipants = ev.EventParticipants,
                        Resources = ev.Resources,
                        Comments = ev.Comments
                    };
   

                _unitOfWork.EventRepository.Update(ev);
                _unitOfWork.Save();

                var page = 1;
                var pageNumber = page != 0 ? page : 1;

                ev.PropertyValues = _unitOfWork.EventPropertyValueRepository.Get().Where(x => x.EventId == ev.EventId).ToList();
                ev.PropertyValuesPaged = ev.PropertyValues.OrderBy(o => o.EventProperty.Name).ToPagedList(_pageSize, pageNumber);

                var propOfType = GetAllProperties(_unitOfWork.EventTypeRepository.Get().FirstOrDefault(t => t.TypeId == ev.EventTypeId));

                foreach (var value in ev.PropertyValues)
                {
                    value.Shadow = !propOfType.Contains(value.EventProperty);
                }

                var listEvPropValue = new List<EventPropertyValue> { };

                foreach (var property in propOfType)
                {
                    if (ev.PropertyValues.Any(v => v.EventProperty == property)) continue;
                    listEvPropValue.Add(new EventPropertyValue() { Event = ev, EventProperty = property, Value = "" });
                }

                ev.PropertyValues = listEvPropValue;
                ev.PropertyValuesPaged = ev.PropertyValues.ToPagedList(1, _pageSize);
   
                _unitOfWork.Save();

                //Clear the Cache
                ClearCache();

                return RedirectToAction("Index");
            }

            ViewBag.EventTypeIdDdl = PopulateEventTypeDropDownList(ev.EventTypeId);
            ViewBag.EntityIdDdl = PopulateEntityDropDownList(ev.EntityId);

            return View(ev);  
        }


        //
        // GET: /Event/Delete/5
        [Authorize]
        public ActionResult Delete(int id = 0)
        {
            if (id != 0)
            {
                Event ev = _unitOfWork.EventRepository.GetByID(id);
                if (ev == null)
                {
                    return HttpNotFound();
                }
                return View(ev);
            }
            else
            {
                ViewBag.MsgWarning = "Para Eliminar um evento tem de selecionar o registo pretendido!";
                return View("Default");
            }
        }


        //
        // POST: /Event/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            Event ev = _unitOfWork.EventRepository.GetByID(id);
            _unitOfWork.EventRepository.Delete(ev);
            _unitOfWork.Save();

            //DELETE FOLDERS AND FILES EVENT
            var pathImg = Server.MapPath(String.Format("~/Content/Event/{0}/Img", ev.EventId));
            var pathDoc = Server.MapPath(String.Format("~/Content/Event/{0}/Doc", ev.EventId));
            var pathEvent = Server.MapPath(String.Format("~/Content/Event/{0}", ev.EventId));
            var folderImg = new DirectoryInfo(pathImg);
            var folderDoc = new DirectoryInfo(pathDoc);
            var folderEvent = new DirectoryInfo(pathEvent);

            if (folderImg.GetFiles().Any())
            {
                foreach (FileInfo file in folderImg.GetFiles())
                {
                    file.Delete();
                }
                foreach (DirectoryInfo dir in folderImg.GetDirectories())
                {
                    dir.Delete(true);
                }
            }
           
            if (folderDoc.GetFiles().Any())
            {
                foreach (FileInfo file in folderDoc.GetFiles())
                {
                    file.Delete();
                }
                foreach (DirectoryInfo dir in folderDoc.GetDirectories())
                {
                    dir.Delete(true);
                }
            }

            if (folderEvent.GetFiles().Any())
            {
                foreach (FileInfo file in folderEvent.GetFiles())
                {
                    file.Delete();
                }
                foreach (DirectoryInfo dir in folderEvent.GetDirectories())
                {
                    dir.Delete(true);
                }
            }

            if (Directory.Exists(pathEvent))
            {
                Directory.Delete(pathEvent);
            }

            return RedirectToAction("Index");
        }

   
        #region EventTypeCRUD
        /*
        public PartialViewResult AddEventTypePv()
        {
            ViewBag.SuperTypeId1 = new SelectList(_unitOfWork.EventTypeRepository.Get(), "TypeId", "Type");
            return PartialView("_AddEventType");
        }

        [HttpPost]
        public PartialViewResult AddEventTypePvPost(EventType eventtype)
        {
            if (ModelState.IsValid)
            {

                _unitOfWork.EventTypeRepository.Insert(eventtype);
                _unitOfWork.Save();
                ViewBag.SuperTypeId1 = new SelectList(_unitOfWork.EventTypeRepository.Get(), "TypeId", "Type");
                return PartialView("_AddEventType");
            }

            ViewBag.SuperTypeId1 = new SelectList(_unitOfWork.EventTypeRepository.Get(), "TypeId", "Type");
            return PartialView("_AddEventType");
        }


        public PartialViewResult EditEventTypePv(int id)
        {
            EventType ev = _unitOfWork.EventTypeRepository.GetByID(id);

            ViewBag.SuperTypeId1 = new SelectList(_unitOfWork.EventTypeRepository.Get(), "TypeId", "Type");
            return PartialView("_EditEventType", ev);
        }

        [HttpPost]
        public PartialViewResult EditEventTypePvPost(EventType eventtype)
        {
            if (ModelState.IsValid)
            {
                _unitOfWork.EventTypeRepository.Update(eventtype);
                _unitOfWork.Save();
                ViewBag.SuperTypeId1 = new SelectList(_unitOfWork.EventTypeRepository.Get(), "TypeId", "Type");
                return PartialView("_EditEventType");
            }

            ViewBag.SuperTypeId1 = new SelectList(_unitOfWork.EventTypeRepository.Get(), "TypeId", "Type");
            return PartialView("_EditEventType");
        }
        */
        #endregion


        //
        // JSON: /Event/UploadPosterImage
        [Authorize]
        public JsonResult UpdatePosterImage(int eventId)
        {
            try
            {
                var ev = new Event();

                HttpPostedFileBase file = Request.Files[0];
                if (file != null && file.ContentLength > 0)
                {
                    var path = "/Images/Icones/icon_no_image.png";
                    var pathBd = path;

                    // Verify that the user selected a file
                    if (file != null && file.ContentLength > 0)
                    {
                        // extract only the fielname
                        var fileName = Path.GetFileName(file.FileName);
                        var pathTemp = String.Format("~/Content/Event/{0}/Img", eventId);
                        var pathTempBd = String.Format("/Content/Event/{0}/Img", eventId);

                        pathBd = pathTempBd + "/" + fileName;
                        path = Path.Combine(Server.MapPath(pathTemp), fileName);

                        if (_CacheMode.Active)
                        {
                            foreach (var item in _CacheMode.EventsList.Where(item => item.EventId == eventId))
                            {
                                item.Poster = pathBd;
                            }

                            //Create folders of Event
                            var pathImg = Server.MapPath(String.Format("~/Content/Event/{0}/Img", eventId));
                            var pathDoc = Server.MapPath(String.Format("~/Content/Event/{0}/Doc", eventId));
                            var pathEvent = Server.MapPath(String.Format("~/Content/Event/{0}", eventId));

                            if (!Directory.Exists(pathEvent))
                                Directory.CreateDirectory(pathEvent);

                            if (!Directory.Exists(pathImg))
                                Directory.CreateDirectory(pathImg);

                            if (!Directory.Exists(pathDoc))
                                Directory.CreateDirectory(pathDoc);
                        }
                        else
                        {
                            ev = _unitOfWork.EventRepository.GetByID(eventId);
                            ev.Poster = pathBd;
                        }

                        file.SaveAs(path);
                        ViewBag.PosterSrc = pathBd;
      
                    }

                    return Json(new {success = true, error = false, path = Url.Content(pathBd)});
                }
                 else
                {
                    return Json(new { success = true, error = "File is empty" });
                }
            }
            catch (Exception e)
            {
                return Json(new { success = false, error = false, msgError = e });
            }

        }
        
        //
        // JSON: /Event/DeletePosterImage
        [Authorize]
        public JsonResult DeletePosterImage(int eventId)
        {
            try
            {
                if (eventId > 0)
                {
                    var ev = _CacheMode.Active ? _CacheMode.EventsList.FirstOrDefault(item => item.EventId == eventId) 
                                               : _unitOfWork.EventRepository.GetByID(eventId);
                    
                    if (ev != null && !ev.Poster.Equals("/Images/Icones/icon_no_image.png"))
                    {
                        string filePath = "~" + ev.Poster;
                        string fileToDelete = null;

                        fileToDelete = Server.MapPath(filePath);

                        System.IO.File.Delete(fileToDelete);

                        ev.Poster = "/Images/Icones/icon_no_image.png";

                        if (_CacheMode.Active)
                        {
                            foreach (var item in _CacheMode.EventsList.Where(item => item.EventId == eventId))
                            {
                                item.Poster = ev.Poster;
                            }
                        }
                        else
                        {
                            _unitOfWork.Save();
                        }
                        return Json(new { success = true, error = false, path = Url.Content(ev.Poster) });
                    }

                    return Json(new {success = true, error = "Ocorreu um erro ao eliminar a imagem!"});
                }

                return Json(new { success = true, error = "Ocorreu um erro ao eliminar a imagem!" });

            }
            catch (Exception e)
            {
                return Json(new {success = false, error = false, msgError = e});
            }

        }
       

        // ///////////////////////////////////////////////////////////////////////////////
        //                               EXPORT ACTIONS                                 //
        // ///////////////////////////////////////////////////////////////////////////////
        
        // GET: /Event/ExportIcal
        [Authorize]
        public ActionResult ExportIcal()
        {
            try
            {
                _pageSize = 9999;
                var eventsListIPaged = BuildEventList(_sortOrderGlobal, _stringFilterGlobal);
                var eventsList = eventsListIPaged.ToList();
                _pageSize = 8;

                if (eventsList.Count > 0)
                {
                    var filePath = Server.MapPath("~/Content/temp/Eventos_em_iCal.ics");
                    if (System.IO.File.Exists(filePath)) System.IO.File.Delete(filePath);
                    TextWriter iCalFile = new StreamWriter(filePath, true);
                    
                    //var iCalFile = new StreamWriter(filePath);
                    var iCalStr = String.Empty;

                    iCalStr += "BEGIN:VCALENDAR\n";
                    iCalStr += "PRODID:-//CultuRAM//Agenda Cutural da RAM v.1.0//PT\n";
                    iCalStr += "VERSION:1.0\n";
                    iCalStr += "CALSCALE:GREGORIAN\n";
                    iCalStr += "METHOD:PUBLISH\n";
                    iCalStr += "X-WR-CALNAME:CultuRAM\n";
                    iCalStr += "X-WR-TIMEZONE:Europe/Lisbon\n";
                    iCalStr += "X-WR-CALDESC:Eventos divulgados na agenda CultuRAM\n\n";

                    foreach (var ev in eventsList)
                    {
                        var idToEncrypt = ev.EventId.ToString(CultureInfo.InvariantCulture);
                        
                        iCalStr += "BEGIN:VEVENT\n";
                        //iCalStrg = iCalStrg + "STATUS: CONFIRMED \n";
                        iCalStr += "UID:" + Md5Encrypt(idToEncrypt, true) + "@culturam.net\n";
                        iCalStr += "DTSTART;VALUE=DATETIME:" + ev.StartDate.ToString("yyyyMMddTHmmss", CultureInfo.InvariantCulture) + "\n";
                        iCalStr += "DTEND;VALUE=DATETIME:" + ev.EndDate.ToString("yyyyMMddTHmmss", CultureInfo.InvariantCulture) + "\n"; 
                        iCalStr += "DURATION:" + ev.Duration + "\n";
                        iCalStr += "SUMMARY:" + ev.Title + "\n";
                        iCalStr += "DESCRIPTION:" + ev.Entity.Name + "\n";
                        iCalStr += "LOCATION:" + ev.GetPropertyValue("Local") + "\n";
                        iCalStr += "END:VEVENT\n\n";
                    }
              
                    iCalStr += "END:VCALENDAR\n";

                    iCalFile.WriteLine(iCalStr);

                    iCalFile.Close();
                   

                    ViewBag.MsgSuccess = "A exportação da lista de eventos para formato iCAL foi concluida com sucesso!";
                }
                else
                {
                    ViewBag.MsgWarning = "Não foi possivel exportar para formato iCAL, porque nenhum evento foi encontrado. Tente novamente!";
                }

                ViewBag.FileType = "ical";
                return PartialView("_Export");
            }
            catch (Exception)
            {
                ViewBag.MsgError = "Ocorreu um erro ao exportar os eventos para formato iCAL. Tente novamente!";
                return PartialView("_Export");
            }
        }

        //
        // GET: /Event/ExportJason
        [Authorize]
        public ActionResult ExportJson()
        {
            try{

                _pageSize = 9999;
                var eventsList = BuildEventList(_sortOrderGlobal, _stringFilterGlobal);
                _pageSize = 8;
                var places = _unitOfWork.PlaceRepository.GetList();
                var place = String.Empty;

                if (eventsList.Count > 0)
                {
                    /* Serialize Events to JSON: AUTO
                    var eventsToJson = JsonConvert.SerializeObject(eventsList, 
                                                Formatting.Indented, 
                                                new JsonSerializerSettings()
                                                    {
                                                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                                                    });*/

                    // Serialize Events to JSON
                    var sb = new StringBuilder();
                    var sw = new StringWriter(sb);
                    var jsonStr = new JsonTextWriter(sw);

                    jsonStr.Formatting = Formatting.Indented;

                    jsonStr.WriteStartObject();
                    jsonStr.WritePropertyName("eventos");
                    jsonStr.WriteStartArray();

                    foreach (var ev in eventsList)
                    {
                        place = ev.GetPropertyValue("Local");

                        jsonStr.WriteStartObject();
                        jsonStr.WritePropertyName("ID");
                        jsonStr.WriteValue(ev.EventId.ToString(CultureInfo.InvariantCulture));
                        jsonStr.WritePropertyName("Tipo");
                        jsonStr.WriteValue(ev.EventType.Type);
                        jsonStr.WritePropertyName("Titulo");
                        jsonStr.WriteValue(ev.Title);
                        jsonStr.WritePropertyName("Data_Inicio");
                        jsonStr.WriteValue(ev.StartDate.ToString(CultureInfo.InvariantCulture));
                        jsonStr.WritePropertyName("Data_Fim");
                        jsonStr.WriteValue(ev.EndDate.ToString(CultureInfo.InvariantCulture));
                        jsonStr.WritePropertyName("Duracao");
                        jsonStr.WriteValue(ev.Duration);
                        jsonStr.WritePropertyName("Local");
                        jsonStr.WriteValue(place);
                        jsonStr.WritePropertyName("Municipio");
                        jsonStr.WriteValue(ev.GetCityValue(place, places));
                        jsonStr.WritePropertyName("Entidade_Promotora");
                        jsonStr.WriteValue(ev.Entity.Name);
                        jsonStr.WritePropertyName("Estado");
                        jsonStr.WriteValue(ev.GetPropertyValue("Estado"));
                        jsonStr.WriteEndObject();
                    }

                    jsonStr.WriteEndArray();
                    jsonStr.WriteEndObject();

                    
                    // Define Location and Name of File
                    const string fileName = "Eventos_em_JSON.json";
                    var filePath = Server.MapPath("~/Content/temp/" + fileName);
                    if (System.IO.File.Exists(filePath)) System.IO.File.Delete(filePath);
                   

                    // Creates the file on server
                    System.IO.File.WriteAllText(filePath, sw.ToString());

                    jsonStr.Close();
                    sw.Close();

                    ViewBag.MsgSuccess = "A exportação da lista de eventos para formato JSON foi concluida com sucesso!";
                }
                else
                {
                    ViewBag.MsgWarning = "Não foi possivel exportar para formato JSON, porque nenhum evento foi encontrado. Tente novamente!";
                }

                ViewBag.FileType = "json";
                return PartialView("_Export");
            }
            catch (Exception)
            {
                ViewBag.MsgError = "Ocorreu um erro ao exportar os eventos para formato JSON. Tente novamente!";
                return PartialView("_Export");
            }
        }

        //
        // GET: /Event/ExportIcal
        [Authorize]
        public ActionResult ExportXml(string sortOrder, string stringFilter)
        {
            try
            {
                _pageSize = 9999;  
                var eventsListIPaged = BuildEventList(_sortOrderGlobal, _stringFilterGlobal);
                var eventsList = eventsListIPaged.ToList();
                _pageSize = 8;
                var places = _unitOfWork.PlaceRepository.GetList();
                var place = String.Empty;

                var filePath = Server.MapPath("~/Content/temp/Eventos_em_XML.xml");
                if (System.IO.File.Exists(filePath)) System.IO.File.Delete(filePath);

                if (eventsList.Count > 0)
                {
                    var xmlStr = new XmlTextWriter(filePath, Encoding.UTF8);
                    xmlStr.WriteStartDocument(true);
                    xmlStr.Formatting = (System.Xml.Formatting) Formatting.Indented;
                    xmlStr.Indentation = 2;
                    xmlStr.WriteStartElement("Eventos");

                    foreach (var ev in eventsList)
                    {
                        place = ev.GetPropertyValue("Local");
                       
                        xmlStr.WriteStartElement("Evento");
                            xmlStr.WriteStartAttribute("ID");
                            xmlStr.WriteString(ev.EventId.ToString(CultureInfo.InvariantCulture));
                            xmlStr.WriteEndAttribute();
                            xmlStr.WriteStartElement("Tipo");
                            xmlStr.WriteString(ev.EventType.Type);
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Titulo");
                            xmlStr.WriteString(ev.Title);
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Data_Inicio");
                            xmlStr.WriteString(ev.StartDate.ToString(CultureInfo.InvariantCulture));
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Data_Fim");
                            xmlStr.WriteString(ev.EndDate.ToString(CultureInfo.InvariantCulture));
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Duracao");
                            xmlStr.WriteString(ev.Duration);
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Local");
                            xmlStr.WriteString(place);
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Municipio");
                            xmlStr.WriteString(ev.GetCityValue(place, places));
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Entidade_Promotora");
                            xmlStr.WriteString(ev.Entity.Name);
                            xmlStr.WriteEndElement();
                            xmlStr.WriteStartElement("Estado");
                            xmlStr.WriteString(ev.GetPropertyValue("Estado"));
                            xmlStr.WriteEndElement();
                        xmlStr.WriteEndElement();
                    }

                    xmlStr.WriteEndElement();
                    xmlStr.WriteEndDocument();
                    xmlStr.Close();
              

                    ViewBag.MsgSuccess = "A exportação da lista de eventos para formato XML foi concluida com sucesso!";
                }
                else
                {
                    ViewBag.MsgWarning = "Não foi possivel exportar para formato XML, porque nenhum evento foi encontrado. Tente novamente!";
                }


                ViewBag.FileType = "xml";
                return PartialView("_Export");
            }
            catch (Exception)
            {
                ViewBag.MsgError = "Ocorreu um erro ao exportar os eventos para formato XML. Tente novamente!";
                return PartialView("_Export");
            }
        }

        //
        // GET: /Event/Download
        [Authorize]
        public FileResult Download(string ft)
        {
            var filePath = String.Empty;
            var fileName = String.Empty;
            var contentType = String.Empty;

            try
            {
                          
                switch (ft)
                {
                    case "ical":
                        fileName = "Eventos_em_ICAL.ics";
                        filePath = Server.MapPath("~/Content/temp/" + fileName);
                        contentType = "text/calendar";
                        break;
                    case "json":
                        fileName = "Eventos_em_JSON.json";
                        filePath = Server.MapPath("~/Content/temp/" + fileName);
                        contentType = "application/json";
                        break;
                    case "xml":
                        fileName = "Eventos_em_XML.xml";
                        filePath = Server.MapPath("~/Content/temp/" + fileName);
                        contentType = "application/xml";
                        break;
                }

                if (System.IO.File.Exists(filePath))
                {
                    return File(filePath, contentType, fileName);
                }

                ViewBag.MsgError = "Ocorreu um erro ao efetuar o download do ficheiro. Tente novamente!";
                return null;

            }
            catch (Exception)
            {
                //return JavaScript(Alert("Hello this is an alert"));
                //ScriptManager.RegisterStartupScript(this.GetType(), "Alert", "Ocorreu um erro...", true);
                return null;
                
                //ViewBag.MsgError = "Ocorreu um erro ao efetuar o download do ficheiro. Tente novamente!";
                //return PartialView("Index");
            }
        }
      


        // ///////////////////////////////////////////////////////////////////////////////
        //                            AUXILIARY FUNCTIONS                               //
        // ///////////////////////////////////////////////////////////////////////////////
        #region AuxFunctions

        //Method: Populate the DropDownList of Participant Types
        private static SelectList PopulateParticipTypeDropDownList(int? selectedParticipTypeId = null)
        {
            var participTypes = _unitOfWork.ParticipantTypeRepository.Get().OrderBy(p => p.ParticipType);
            return selectedParticipTypeId == null ? new SelectList(participTypes, "ParticipTypeId", "ParticipType") : 
                                                    new SelectList(participTypes, "ParticipTypeId", "ParticipType", selectedParticipTypeId);
        }

        //Method: Populate the DropDownList of Participants
        private static SelectList PopulateParticipDropDownList(int? selectedParticipId = null)
        {
            var particip = _unitOfWork.ParticipantRepository.Get().OrderBy(o => o.Name);
            return selectedParticipId == null ? new SelectList(particip, "ParticipId", "Name") : 
                                                new SelectList(particip, "ParticipId", "Name", selectedParticipId);
        }

        //Method: Populate the DropDownList of Event Types
        private static SelectList PopulateEventTypeDropDownList(int? selectedEventTypeId = null)
        {
            var eeventTypes = _unitOfWork.EventTypeRepository.Get().OrderBy(o => o.Type);
            return selectedEventTypeId == null ? new SelectList(eeventTypes, "TypeId", "Type") : 
                                                 new SelectList(eeventTypes, "TypeId", "Type", selectedEventTypeId);
        }

        //Method: Populate the DropDownList of Entity Types
        private static SelectList PopulateEntityTypeDropDownList(int? selectedEntityTypeId = null)
        {
            var entityTypes = _unitOfWork.EntityTypeRepository.Get().OrderBy(o => o.EntityTypeName);
            return selectedEntityTypeId == null ? new SelectList(entityTypes, "EntityTypeId", "EntityTypeName") : 
                                                  new SelectList(entityTypes, "EntityTypeId", "EntityTypeName", selectedEntityTypeId);
        }

        //Method: Populate the DropDownList of Entities 
        private static SelectList PopulateEntityDropDownList(int? selectedEntityId = null)
        {
            var entities = _unitOfWork.EntityRepository.Get().OrderBy(et => et.Name);
            return selectedEntityId == null ? new SelectList(entities, "EntityId", "Name") : 
                                              new SelectList(entities, "EntityId", "Name", selectedEntityId);
        }

        //Method: Populate the DropDownList of States 
        private static SelectList PopulateStatesDropDownList(int? selectedStateId = null)
        {
            var states = _unitOfWork.EventStateRepository.Get().OrderBy(o => o.State);
            return selectedStateId == null ? new SelectList(states, "StateId", "State") : 
                                             new SelectList(states, "StateId", "State", selectedStateId);
        }

        //Method: Populate the DropDownList of Places 
        private static SelectList PopulatePlacesDropDownList(int? selectedPlaceId = null)
        {
            var places = _unitOfWork.PlaceRepository.Get().OrderBy(o => o.NamePlace);
            return selectedPlaceId == null ? new SelectList(places, "PlaceId", "NamePlace") : 
                                             new SelectList(places, "PlaceId", "NamePlace", selectedPlaceId);
        }

        //Method: Populate the DropDownList of Cities 
        private static SelectList PopulateCitiesDropDownList(int? selectedCityId = null)
        {
            var cities = _unitOfWork.CityRepository.Get().OrderBy(o => o.CityName);
            return selectedCityId == null ? new SelectList(cities, "CityId", "CityName") : 
                                            new SelectList(cities, "CityId", "CityName", selectedCityId);
        }

        //Method: Populate the DropDownList of Periods 
        private static SelectList PopulatePeriodDropDownList()
        {
            //ViewBag.PeriodIdEv
            return new SelectList(new[]{
                                  new SelectListItem{ Text="Período", Value="0", Selected = true},
                                  new SelectListItem{ Text="Dia", Value="d"},
                                  new SelectListItem{ Text="Semana", Value="w"},
                                  new SelectListItem{ Text="15 Dias", Value="15d"},
                                  new SelectListItem{ Text="Mês", Value="m"},
                                  new SelectListItem{ Text="Trimestre", Value="t"},
                                  new SelectListItem{ Text="Ano", Value="y"}}, "Value", "Text");
        }

        //Method: Get all properties of EventType
        private static IList<EventProperty> GetAllProperties(EventType aEventType)
        {
            var properties = new List<EventProperty>();

            for (var t = aEventType; t != null; t = t.SuperType)
            {
                properties.AddRange(t.EventProperties);
            }
            return properties;
        }

        //Method: Clear Cache
        public static void ClearCache()
        {
            _CacheMode = new CacheMode()
            {
                EventsList = new List<Event>(),
                EventPropValuesList = new List<EventPropertyValue>(),
                SessionsList = new List<Session>(),
                ParticipantsList = new List<EventParticipant>(),
                ResourcesList = new List<Resource>(),
                Active = false
            };
        }

        //Method: MD5 Encrypt 
        public static string Md5Encrypt(string toEncrypt, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);

            var settingsReader = new AppSettingsReader();

            var key = (string) settingsReader.GetValue("SecurityKey", typeof (String));

            if (useHashing)
            {
                var hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(key));
                hashmd5.Clear();
            }
            else
            {
                keyArray = Encoding.UTF8.GetBytes(key);
            }

            var tdes = new TripleDESCryptoServiceProvider
                {
                    Key = keyArray,
                    Mode = CipherMode.ECB,
                    Padding = PaddingMode.PKCS7
                };

            var cTransform = tdes.CreateEncryptor();   
            var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
             
            tdes.Clear();
            
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        //Method: MD5 Decrypt  
        public static string Md5Decrypt(string cipherString, bool useHashing)
        {
            byte[] keyArray;
            var toEncryptArray = Convert.FromBase64String(cipherString);
            var settingsReader = new AppSettingsReader();
            var key = (string)settingsReader.GetValue("SecurityKey", typeof(String));

            if (useHashing)
            {
                var hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(key));

                hashmd5.Clear();
            }
            else
            {
                keyArray = Encoding.UTF8.GetBytes(key);
            }

            var tdes = new TripleDESCryptoServiceProvider
                {
                    Key = keyArray,
                    Mode = CipherMode.ECB,
                    Padding = PaddingMode.PKCS7
                };


            var cTransform = tdes.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
               
            tdes.Clear();
 
            return Encoding.UTF8.GetString(resultArray);
        }

        //Method: Build Events List
        private IPagedList<Event> BuildEventList(string sortOrder, string stringFilter, int page = 0)
        {
            var test = _unitOfWork.EventRepository.GetList();


            _sortOrderGlobal = sortOrder;
            _stringFilterGlobal = stringFilter;

            #region sortVariables

            ViewBag.CurrentSort = sortOrder;
            ViewBag.TypeSortParm = sortOrder == "Type" ? "Type desc" : "Type";
            ViewBag.TitleSortParm = sortOrder == "Title" ? "Title desc" : "Title";
            ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
            ViewBag.TimeSortParm = sortOrder == "Time" ? "Time desc" : "Time";
            ViewBag.PlaceSortParm = sortOrder == "Place" ? "Place desc" : "Place";
            ViewBag.StateSortParm = sortOrder == "State" ? "State desc" : "State";
            ViewBag.PublicSortParm = sortOrder == "Public" ? "Public desc" : "Public";
            ViewBag.EntitySortParm = sortOrder == "Entity" ? "Entity desc" : "Entity";

            ViewBag.IconSortType = "chevron-updown";
            ViewBag.IconSortTitle = "chevron-updown";
            ViewBag.IconSortDate = "chevron-updown";
            ViewBag.IconSortTime = "chevron-updown";
            ViewBag.IconSortPlace = "chevron-updown";
            ViewBag.IconSortState = "chevron-updown";
            ViewBag.IconSortPublic = "chevron-updown";
            ViewBag.IconSortEntity = "chevron-updown";

            #endregion

            ViewBag.CurrentFilter = stringFilter;

            //var events = from s in db.Events select s;
            var events = _unitOfWork.EventRepository.Get();

            if (!Request.HttpMethod.Equals("GET"))
            {
                page = 1;
            }
        
            int pageNumber = 0;
            //int pageSize = 8;

            var dTxtDateStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day) + new TimeSpan(00, 00, 0); ;
            var dTxtDateEnd = dTxtDateStart.AddYears(1) + new TimeSpan(23, 59, 59);

            var entityIdUserAuth = vLogin.GetEntityUser();

            if (!String.IsNullOrEmpty(stringFilter))
            {
                //var _stringFilter = stringFilter.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                var strFilter = stringFilter.Split(new string[] {","}, StringSplitOptions.None);

                var ddlType = strFilter[0];
                var txtTitle = strFilter[1];
                var txtDateStart = strFilter[3];
                var txtDateEnd = strFilter[4];
                var ddlPeriod = strFilter[5];
                var ddlPlace = strFilter[6];
                var ddlState = strFilter[7];
                var radPublic = strFilter[8];
                var ddlEntity = strFilter[9];


                //if (!DateTime.TryParse(txtDate, out dTxtDate))
                //    dTxtDate = new DateTime(DateTime.Now.Year, 1, 1);

                if (!txtDateStart.Equals(String.Empty))
                    dTxtDateStart = DateTime.Parse(txtDateStart);

                if (!txtDateEnd.Equals(String.Empty))
                    dTxtDateEnd = DateTime.Parse(txtDateEnd);


                switch (ddlPeriod)
                {
                    case "d":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date + new TimeSpan(24, 00, 0);
                        break;
                    case "w":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddDays(7) + new TimeSpan(23, 59, 59);
                        break;
                    case "15d":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddDays(15) + new TimeSpan(23, 59, 59);
                        break;
                    case "m":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddMonths(1) + new TimeSpan(24, 00, 0);
                        break;
                    case "t":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddMonths(3) + new TimeSpan(23, 59, 59);
                        break;
                    case "y":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddYears(1) + new TimeSpan(24, 00, 0);
                        break;
                }


                //var compare = new Func<DateTime, DateTime, int>(( DateTime d1, DateTime d2) => DateTime.Compare(d1.Date, d2.Date));
                if (vLogin.ValUserRole("Administrador do Sistema"))
                {
                    if (!radPublic.Equals("na"))
                    {
                        var radPublicBool = radPublic.Equals("true") ? true : false;

                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.Public.Equals(radPublicBool) &&
                                                          evt.Entity.Name.Contains(ddlEntity)
                            );
                    }
                    else
                    {
                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.Entity.Name.Contains(ddlEntity)
                            );
                    }
                }
                else
                {
                    if (!radPublic.Equals("na"))
                    {
                        var radPublicBool = radPublic.Equals("true") ? true : false;

                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.Public.Equals(radPublicBool) &&
                                                          evt.Entity.Name.Contains(ddlEntity) &&
                                                          (evt.Public.Equals(true) || evt.EntityId == entityIdUserAuth)
                            );
                    }
                    else
                    {
                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.Entity.Name.Contains(ddlEntity) &&
                                                          (evt.Public.Equals(true) || evt.EntityId == entityIdUserAuth)
                            );
                    }
                }            
            }
            else
            {
                events = vLogin.ValUserRole("Administrador do Sistema")
                             ? _unitOfWork.EventRepository.Get()
                                          .Where(evt => evt.StartDate >= dTxtDateStart && evt.StartDate <= dTxtDateEnd)
                             : _unitOfWork.EventRepository.Get()
                                          .Where(
                                              evt => evt.StartDate >= dTxtDateStart && evt.StartDate <= dTxtDateEnd &&
                                                     (evt.Public.Equals(true) || evt.EntityId == entityIdUserAuth));
            }

            /*
            //DETERMINAR O NUMERO DA PAGINA ONDE COMECAM OS EVENTOS DA DATA ATUAL
            var eventsTemp = events.Select(ev => ev.StartDate <= DateTime.Now && ev.StartDate >= dTxtDateStart);

            var numPartialEvents = eventsTemp.Count(et => et != false);

            if (page == 0)
            {
                var pageTemp = Math.Ceiling((double) numPartialEvents / _pageSize);
                page = (numPartialEvents % _pageSize) == 0 ? (int) pageTemp + 1 : (int) pageTemp;
            }*/


            //pageNumber = page;
            //pageNumber = (page ?? 1);
            pageNumber = page == 0 ? 1 : page;


            #region ordination
            switch (sortOrder)
            {
                case "Type":
                    events = events.OrderBy(s => s.EventType.Type);
                    ViewBag.IconSortType = "chevron-up";
                    break;
                case "Type desc":
                    events = events.OrderByDescending(s => s.EventType.Type);
                    ViewBag.IconSortType = "chevron-down";
                    break;
                case "Title":
                    events = events.OrderBy(s => s.Title);
                    ViewBag.IconSortTitle = "chevron-up";
                    break;
                case "Title desc":
                    events = events.OrderByDescending(s => s.Title);
                    ViewBag.IconSortTitle = "chevron-down";
                    break;
                case "Date":
                    events = events.OrderBy(s => s.StartDate);
                    ViewBag.IconSortDate = "chevron-up";
                    break;
                case "Date desc":
                    events = events.OrderByDescending(s => s.StartDate);
                    ViewBag.IconSortDate = "chevron-down";
                    break;
                case "Time":
                    //events = events.OrderBy(s => s.Date).ThenBy(s => s.Date.ToShortTimeString());
                    ViewBag.IconSortTime = "chevron-up";
                    break;
                case "Time desc":
                    // events = events.OrderByDescending(s => s.Date).ThenByDescending(s => s.Date.ToShortTimeString());
                    ViewBag.IconSortTime = "chevron-down";
                    break;
                case "Place":
                    events = events.OrderBy(s =>
                        {
                            var propertyValue = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 1);
                            return propertyValue != null ? propertyValue.Value : null;
                        });
                    ViewBag.IconSortPlace = "chevron-up";
                    break;
                case "Place desc":
                    events = events.OrderByDescending(s =>
                        {
                            var orDefault = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 1);
                            return orDefault != null ? orDefault.Value : null;
                        });
                    ViewBag.IconSortPlace = "chevron-down";
                    break;
                case "State":
                    events = events.OrderBy(s =>
                        {
                            var eventPropertyValue = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 2);
                            return eventPropertyValue != null ? eventPropertyValue.Value : null;
                        });
                    ViewBag.IconSortState = "chevron-up";
                    break;
                case "State desc":
                    events = events.OrderByDescending(s =>
                        {
                            var firstOrDefault = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 2);
                            return firstOrDefault != null ? firstOrDefault.Value : null;
                        });
                    ViewBag.IconSortState = "chevron-down";
                    break;
                case "Public":
                    events = events.OrderBy(s => s.Public);
                    ViewBag.IconSortPublic = "chevron-up";
                    break;
                case "Public desc":
                    events = events.OrderByDescending(s => s.Public);
                    ViewBag.IconSortPublic = "chevron-down";
                    break;
                case "Entity":
                    events = events.OrderBy(s => s.Entity.Name);
                    ViewBag.IconSortEntity = "chevron-up";
                    break;
                case "Entity desc":
                    events = events.OrderByDescending(s => s.Entity.Name);
                    ViewBag.IconSortEntity = "chevron-down";
                    break;
                default:
                    events = events.OrderBy(s => s.StartDate);
                    ViewBag.IconSortDate = "chevron-down";
                    break;
            }
            #endregion

            return events.ToPagedList(pageNumber, _pageSize);
        }


        // ======================================================================================
        // BUILD EVENT LIST HIGHLIGHT
        // ======================================================================================
        private IPagedList<Event> BuildEventListHl(string sortOrder, string stringFilter, int page = 0)
        {
            var test = _unitOfWork.EventRepository.GetList();


            _sortOrderGlobal = sortOrder;
            _stringFilterGlobal = stringFilter;

            #region sortVariables

            ViewBag.CurrentSort = sortOrder;
            ViewBag.TypeSortParm = sortOrder == "Type" ? "Type desc" : "Type";
            ViewBag.TitleSortParm = sortOrder == "Title" ? "Title desc" : "Title";
            ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
            ViewBag.TimeSortParm = sortOrder == "Time" ? "Time desc" : "Time";
            ViewBag.PlaceSortParm = sortOrder == "Place" ? "Place desc" : "Place";
            ViewBag.StateSortParm = sortOrder == "State" ? "State desc" : "State";
            ViewBag.PublicSortParm = sortOrder == "Public" ? "Public desc" : "Public";
            ViewBag.EntitySortParm = sortOrder == "Entity" ? "Entity desc" : "Entity";

            ViewBag.IconSortType = "chevron-updown";
            ViewBag.IconSortTitle = "chevron-updown";
            ViewBag.IconSortDate = "chevron-updown";
            ViewBag.IconSortTime = "chevron-updown";
            ViewBag.IconSortPlace = "chevron-updown";
            ViewBag.IconSortState = "chevron-updown";
            ViewBag.IconSortPublic = "chevron-updown";
            ViewBag.IconSortEntity = "chevron-updown";

            #endregion

            ViewBag.CurrentFilter = stringFilter;

            //var events = from s in db.Events select s;
            var events = _unitOfWork.EventRepository.Get();

            if (!Request.HttpMethod.Equals("GET"))
            {
                page = 1;
            }

            int pageNumber = 0;
            //int pageSize = 8;

            var dTxtDateStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day) + new TimeSpan(00, 00, 0); ;
            var dTxtDateEnd = dTxtDateStart.AddYears(1) + new TimeSpan(23, 59, 59);

            var entityIdUserAuth = vLogin.GetEntityUser();

            if (!String.IsNullOrEmpty(stringFilter))
            {
                //var _stringFilter = stringFilter.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                var strFilter = stringFilter.Split(new string[] { "," }, StringSplitOptions.None);

                var ddlType = strFilter[0];
                var txtTitle = strFilter[1];
                var txtDateStart = strFilter[3];
                var txtDateEnd = strFilter[4];
                var ddlPeriod = strFilter[5];
                var ddlPlace = strFilter[6];
                var ddlState = strFilter[7];
                var radPublic = strFilter[8];
                var ddlEntity = strFilter[9];


                //if (!DateTime.TryParse(txtDate, out dTxtDate))
                //    dTxtDate = new DateTime(DateTime.Now.Year, 1, 1);

                if (!txtDateStart.Equals(String.Empty))
                    dTxtDateStart = DateTime.Parse(txtDateStart);

                if (!txtDateEnd.Equals(String.Empty))
                    dTxtDateEnd = DateTime.Parse(txtDateEnd);


                switch (ddlPeriod)
                {
                    case "d":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date + new TimeSpan(24, 00, 0);
                        break;
                    case "w":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddDays(7) + new TimeSpan(23, 59, 59);
                        break;
                    case "15d":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddDays(15) + new TimeSpan(23, 59, 59);
                        break;
                    case "m":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddMonths(1) + new TimeSpan(24, 00, 0);
                        break;
                    case "t":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddMonths(3) + new TimeSpan(23, 59, 59);
                        break;
                    case "y":
                        dTxtDateStart = DateTime.Now.Date + new TimeSpan(00, 00, 0);
                        dTxtDateEnd = DateTime.Now.Date.AddYears(1) + new TimeSpan(24, 00, 0);
                        break;
                }


                //var compare = new Func<DateTime, DateTime, int>(( DateTime d1, DateTime d2) => DateTime.Compare(d1.Date, d2.Date));
                if (vLogin.ValUserRole("Administrador do Sistema"))
                {
                    if (!radPublic.Equals("na"))
                    {
                        var radPublicBool = radPublic.Equals("true") ? true : false;

                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.HasPropertyNullOrEqual("Destaque", "Sim") &&
                                                          evt.Public.Equals(radPublicBool) &&
                                                          evt.Entity.Name.Contains(ddlEntity)
                            );
                    }
                    else
                    {
                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.HasPropertyNullOrEqual("Destaque", "Sim") &&
                                                          evt.Entity.Name.Contains(ddlEntity)
                            );
                    }
                }
                else
                {
                    if (!radPublic.Equals("na"))
                    {
                        var radPublicBool = radPublic.Equals("true") ? true : false;

                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.HasPropertyNullOrEqual("Destaque", "Sim") &&
                                                          evt.Public.Equals(radPublicBool) &&
                                                          evt.Entity.Name.Contains(ddlEntity) &&
                                                          (evt.Public.Equals(true) || evt.EntityId == entityIdUserAuth)
                            );
                    }
                    else
                    {
                        events = _unitOfWork.EventRepository.Get()
                                            .Where(evt => evt.EventType.Type.Contains(ddlType) &&
                                                          evt.Title.ToLower().Contains(txtTitle) &&
                                                          evt.StartDate >= dTxtDateStart &&
                                                          evt.StartDate <= dTxtDateEnd &&
                                                          evt.HasPropertyNullOrEqual("Local", ddlPlace) &&
                                                          evt.HasPropertyNullOrEqual("Estado", ddlState) &&
                                                          evt.HasPropertyNullOrEqual("Destaque", "Sim") &&
                                                          evt.Entity.Name.Contains(ddlEntity) &&
                                                          (evt.Public.Equals(true) || evt.EntityId == entityIdUserAuth)
                            );
                    }
                }
            }
            else
            {
                events = vLogin.ValUserRole("Administrador do Sistema")
                             ? _unitOfWork.EventRepository.Get()
                                          .Where(
                                                evt => //evt.StartDate >= dTxtDateStart && 
                                                //evt.StartDate <= dTxtDateEnd && 
                                                evt.HasPropertyNullOrEqual("Destaque", "Sim"))
                             : _unitOfWork.EventRepository.Get()
                                          .Where(
                                              evt => //evt.StartDate >= dTxtDateStart && 
                                                //evt.StartDate <= dTxtDateEnd &&
                                                  (evt.Public.Equals(true) || evt.EntityId == entityIdUserAuth) &&
                                                  evt.HasPropertyNullOrEqual("Destaque", "Sim"));
            }

            pageNumber = page == 0 ? 1 : page;

            #region ordination
            switch (sortOrder)
            {
                case "Type":
                    events = events.OrderBy(s => s.EventType.Type);
                    ViewBag.IconSortType = "chevron-up";
                    break;
                case "Type desc":
                    events = events.OrderByDescending(s => s.EventType.Type);
                    ViewBag.IconSortType = "chevron-down";
                    break;
                case "Title":
                    events = events.OrderBy(s => s.Title);
                    ViewBag.IconSortTitle = "chevron-up";
                    break;
                case "Title desc":
                    events = events.OrderByDescending(s => s.Title);
                    ViewBag.IconSortTitle = "chevron-down";
                    break;
                case "Date":
                    events = events.OrderBy(s => s.StartDate);
                    ViewBag.IconSortDate = "chevron-up";
                    break;
                case "Date desc":
                    events = events.OrderByDescending(s => s.StartDate);
                    ViewBag.IconSortDate = "chevron-down";
                    break;
                case "Time":
                    //events = events.OrderBy(s => s.Date).ThenBy(s => s.Date.ToShortTimeString());
                    ViewBag.IconSortTime = "chevron-up";
                    break;
                case "Time desc":
                    // events = events.OrderByDescending(s => s.Date).ThenByDescending(s => s.Date.ToShortTimeString());
                    ViewBag.IconSortTime = "chevron-down";
                    break;
                case "Place":
                    events = events.OrderBy(s =>
                    {
                        var propertyValue = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 1);
                        return propertyValue != null ? propertyValue.Value : null;
                    });
                    ViewBag.IconSortPlace = "chevron-up";
                    break;
                case "Place desc":
                    events = events.OrderByDescending(s =>
                    {
                        var orDefault = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 1);
                        return orDefault != null ? orDefault.Value : null;
                    });
                    ViewBag.IconSortPlace = "chevron-down";
                    break;
                case "State":
                    events = events.OrderBy(s =>
                    {
                        var eventPropertyValue = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 2);
                        return eventPropertyValue != null ? eventPropertyValue.Value : null;
                    });
                    ViewBag.IconSortState = "chevron-up";
                    break;
                case "State desc":
                    events = events.OrderByDescending(s =>
                    {
                        var firstOrDefault = s.PropertyValues.FirstOrDefault(x => x.EventPropertyId == 2);
                        return firstOrDefault != null ? firstOrDefault.Value : null;
                    });
                    ViewBag.IconSortState = "chevron-down";
                    break;
                case "Public":
                    events = events.OrderBy(s => s.Public);
                    ViewBag.IconSortPublic = "chevron-up";
                    break;
                case "Public desc":
                    events = events.OrderByDescending(s => s.Public);
                    ViewBag.IconSortPublic = "chevron-down";
                    break;
                case "Entity":
                    events = events.OrderBy(s => s.Entity.Name);
                    ViewBag.IconSortEntity = "chevron-up";
                    break;
                case "Entity desc":
                    events = events.OrderByDescending(s => s.Entity.Name);
                    ViewBag.IconSortEntity = "chevron-down";
                    break;
                default:
                    events = events.OrderBy(s => s.StartDate);
                    ViewBag.IconSortDate = "chevron-down";
                    break;
            }
            #endregion

            return events.ToPagedList(pageNumber, _pageSize);
        }



        #endregion
    }
}

